home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / IDE / SUBARTIC / SUB_ARCT / CONSTRAI / STD_CONS.JAV < prev    next >
Encoding:
Text File  |  1996-10-04  |  38.5 KB  |  1,116 lines

  1.  
  2. package sub_arctic.constraints;
  3.  
  4. import sub_arctic.lib.interactor;
  5. import sub_arctic.lib.interactor_consts;
  6. import sub_arctic.lib.manager;
  7. import sub_arctic.lib.sub_arctic_error;
  8.  
  9. import java.util.Vector;
  10.  
  11. /**
  12.  * Class that provides the implementation for standard lightweight constraints.  
  13.  * This class understand how to encode and decode an integer encoding of 
  14.  * a constraint, and use that to perform operations such as evaluate the 
  15.  * constraint, determine if it depends upon a particular value, produce a 
  16.  * human readable rendition of the constraint, etc. <p>
  17.  *
  18.  * There should only be one instance of this class created: 
  19.  * std_constraint_impl.the_impl().  This should be shared by all constraints.
  20.  * encoded in standard form.<p>
  21.  *
  22.  * In order to organize this class into more manageable units, it is 
  23.  * actually implemented with four helper classes, one for each of the 
  24.  * possible numbers of operands to the constraint.  These are: op0_impl, 
  25.  * op1_impl, op2_impl, and op3_impl.  See those classes for full encoding 
  26.  * details.<p>
  27.  *
  28.  * @see sub_arctic.constraints.op0_impl
  29.  * @see sub_arctic.constraints.op1_impl
  30.  * @see sub_arctic.constraints.op2_impl
  31.  * @see sub_arctic.constraints.op3_impl
  32.  * @author Scott Hudson
  33.  */
  34. public class std_constraint_impl 
  35.   implements constraint_impl, std_encoding_consts {
  36.  
  37.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  38.  
  39.   /** 
  40.    * Protected constructor -- no instances of this class should be created
  41.    * outside the one stored statically with the class (the_impl).
  42.    */
  43.   protected std_constraint_impl() { }
  44.  
  45.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  46.  
  47.   /** The one and only instance of this class. This instance should be shared
  48.    *  by all constraints encoded in standard form. */
  49.   protected static final std_constraint_impl _the_impl 
  50.     = new std_constraint_impl();
  51.  
  52.   /** The one and only instance of this class. This instance should be shared
  53.    *  by all constraints encoded in standard form. */
  54.   public static std_constraint_impl the_impl() {return _the_impl;}
  55.  
  56.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  57.  
  58.   /** 
  59.    * Determine which kind of constraint (how many operands) the given 
  60.    * encoding has. <p>
  61.    *
  62.    * @param int enc the encoding for the constraint.
  63.    * @return int the number of operands in the encoded constraint.
  64.    */
  65.   public int num_ops(int enc)
  66.     {
  67.       int low5, mid5;
  68.  
  69.       /* pull off the low order 5 bits */
  70.       low5 = enc & 0x1f;
  71.  
  72.       /* 0 => 3 op */
  73.       if (low5 == 0) return 3;
  74.  
  75.       /* 1 => 0 or 1 */
  76.       if (low5 == 1)
  77.     {
  78.       /* pull off next 5 bits */
  79.       mid5 = enc & 0x1e0;
  80.  
  81.       /* 0 => 0 op, anything else is a 1 op */
  82.       if (mid5 == 0) return 0; else return 1;
  83.     }
  84.       /* anything else in lower 5 bits => 2 op */
  85.       return 2;
  86.     }
  87.  
  88.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  89.  
  90.   /**
  91.    * Create a human readable string corresponding to the constant contained in
  92.    * the given encoded constraint. <p>
  93.    *
  94.    * @param int enc the constraint encoding
  95.    * @return String a string depicting the designator
  96.    */
  97.    public String const_str(int enc)
  98.      {
  99.        switch(num_ops(enc))
  100.      {
  101.        case 0: return Integer.toString(op0_impl.const_val(enc));
  102.        case 1: return Integer.toString(op1_impl.const_val(enc));
  103.        case 2: return Integer.toString(op2_impl.const_val(enc));
  104.        case 3: return Integer.toString(op3_impl.const_val(enc));
  105.        default: return "ERROR";
  106.      }
  107.      }
  108.  
  109.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  110.  
  111.   /** 
  112.    * Create a human readable string corresponding to an object/part designator.
  113.    * 
  114.    * @param int enc the designator encoding
  115.    * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
  116.    * @return String a string depicting the designator
  117.    */
  118.   public String obj_part_str(int enc, int orient)
  119.     {
  120.       int obj_code = (enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
  121.       int prt_code = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
  122.  
  123.       if (orient == HORIZONTAL)
  124.         return OBJCODE_strings[obj_code] + "." + PARTCODE_strings_h[prt_code];
  125.       else
  126.         return OBJCODE_strings[obj_code] + "." + PARTCODE_strings_v[prt_code];
  127.     }
  128.   
  129.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  130.  
  131.   /** 
  132.    * Create a human readable string corresponding to the op_code from the 
  133.    * given constraint encoding.
  134.    * 
  135.    * @param int enc the constraint encoding
  136.    * @return String a human readable string with the extracted op code
  137.    */
  138.   public String opcode_str(int enc)
  139.     {
  140.        switch(num_ops(enc))
  141.      {
  142.        case 0: return OP0_strings[op0_impl.op_code(enc)-OP0_MIN];
  143.        case 1: return OP1_strings[op1_impl.op_code(enc)-OP1_MIN];
  144.        case 2: return OP2_strings[op2_impl.op_code(enc)-OP2_MIN];
  145.        case 3: return OP3_strings[op3_impl.op_code(enc)-OP3_MIN];
  146.        default: return "ERROR";
  147.      }
  148.     }
  149.  
  150.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  151.  
  152.   /** 
  153.    * Create a human readable string corresponding to the operands of the 
  154.    * given constraint encoding.
  155.    *
  156.    * @param int enc    the constraint encoding
  157.    * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
  158.    * @return String a human readable string for the operands
  159.    */
  160.   public String operand_str(int enc, int orient)
  161.     {
  162.        switch(num_ops(enc))
  163.      {
  164.        case 0: return "(" + op0_impl.const_val(enc)                 + ")";
  165.        case 1: return "(" + obj_part_str(op1_impl.op1(enc), orient) + "," +
  166.                 op1_impl.const_val(enc)                 + ")";
  167.        case 2: return "(" + obj_part_str(op2_impl.op1(enc), orient) + "," + 
  168.                         obj_part_str(op2_impl.op2(enc), orient) + "," +
  169.                 op2_impl.const_val(enc)                 + ")";
  170.        case 3: return "(" + obj_part_str(op3_impl.op1(enc), orient) + "," + 
  171.                         obj_part_str(op3_impl.op2(enc), orient) + "," +
  172.                             obj_part_str(op3_impl.op3(enc), orient) + "," +
  173.                 op3_impl.const_val(enc)                 + ")";
  174.        default: return "(ERROR)";
  175.      }
  176.     }
  177.  
  178.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  179.  
  180.   /** 
  181.    * Create a human readable string corresponding to the given constraint
  182.    * encoding.
  183.    *
  184.    * @param int enc    the constraint encoding
  185.    * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
  186.    * @return String a human readable string for the constraint
  187.    */
  188.   public String str_for(int enc, int orient)
  189.     {
  190.       return opcode_str(enc) + operand_str(enc, orient);
  191.     }
  192.  
  193.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  194.  
  195.   /** 
  196.    * Create a terse human readable string corresponding to an object/part 
  197.    * designator.
  198.    * 
  199.    * @param int enc    the designator encoding
  200.    * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
  201.    * @return String a string depicting the designator
  202.    */
  203.   public String obj_part_tag(int enc, int orient)
  204.     {
  205.       int obj_code = (enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
  206.       int prt_code = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
  207.  
  208.       if (orient == HORIZONTAL)
  209.         return OBJCODE_tags[obj_code] + "." + PARTCODE_tags_h[prt_code];
  210.       else
  211.         return OBJCODE_tags[obj_code] + "." + PARTCODE_tags_v[prt_code];
  212.     }
  213.   
  214.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  215.  
  216.   /** 
  217.    * Create a terse human readable string corresponding to the op_code from the 
  218.    * given constraint encoding.
  219.    * 
  220.    * @param int enc the constraint encoding
  221.    * @return String a human readable string with the extracted op code
  222.    */
  223.   public String opcode_tag(int enc)
  224.     {
  225.        switch(num_ops(enc))
  226.      {
  227.        case 0: return OP0_tags[op0_impl.op_code(enc)-OP0_MIN];
  228.        case 1: return OP1_tags[op1_impl.op_code(enc)-OP1_MIN];
  229.        case 2: return OP2_tags[op2_impl.op_code(enc)-OP2_MIN];
  230.        case 3: return OP3_tags[op3_impl.op_code(enc)-OP3_MIN];
  231.        default: return "ERROR";
  232.      }
  233.     }
  234.  
  235.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  236.  
  237.   /** 
  238.    * Create a terse human readable string corresponding to the operands of the 
  239.    * given constraint encoding.
  240.    *
  241.    * @param int enc    the constraint encoding
  242.    * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
  243.    * @return String a human readable string for the operands
  244.    */
  245.   public String operand_tag(int enc, int orient)
  246.     {
  247.        switch(num_ops(enc))
  248.      {
  249.        case 0: return "(" + op0_impl.const_val(enc)                + ")";
  250.        case 1: return "(" + obj_part_tag(op1_impl.op1(enc),orient) + "," +
  251.                 op1_impl.const_val(enc)                + ")";
  252.        case 2: return "(" + obj_part_tag(op2_impl.op1(enc),orient) + "," + 
  253.                         obj_part_tag(op2_impl.op2(enc),orient) + "," +
  254.                 op2_impl.const_val(enc)                + ")";
  255.        case 3: return "(" + obj_part_tag(op3_impl.op1(enc),orient) + "," + 
  256.                         obj_part_tag(op3_impl.op2(enc),orient) + "," +
  257.                             obj_part_tag(op3_impl.op3(enc),orient) + "," +
  258.                 op3_impl.const_val(enc)                + ")";
  259.        default: return "(ERROR)";
  260.      }
  261.     }
  262.  
  263.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  264.  
  265.   /** 
  266.    * Create a terse human readable string corresponding to the given constraint
  267.    * encoding.
  268.    *
  269.    * @param int enc the constraint encoding
  270.    * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
  271.    * @return String a human readable string for the constraint
  272.    */
  273.   public String tag_for(int enc, int orient)
  274.     {
  275.       return opcode_tag(enc) + operand_tag(enc, orient);
  276.     }
  277.  
  278.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  279.  
  280.   /* Part constants copied over from interactor_consts for convenience. */
  281.   protected static final int X = interactor_consts.X;
  282.   protected static final int Y = interactor_consts.Y;
  283.   protected static final int W = interactor_consts.W;
  284.   protected static final int H = interactor_consts.H;
  285.   protected static final int VISIBLE = interactor_consts.VISIBLE;
  286.   protected static final int ENABLED = interactor_consts.ENABLED;
  287.   protected static final int PART_A  = interactor_consts.PART_A;
  288.   protected static final int PART_B  = interactor_consts.PART_B;
  289.  
  290.    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  291.  
  292.    /** Fetch a particular value on behalf of a given part in a particular
  293.     *  orientation.  This is used for non-parent values only. No coord transform
  294.     *  is applied to the value before it is returned<p>
  295.     *
  296.     * @see std_constraint_impl#get_parent_value
  297.     * @param interactor from_obj  object we are getting the value from
  298.     * @param int        from_part component of that object we want
  299.     * @param int        orient    orientation (should be HORIZONTAL or VERTICAL)
  300.     * @returns int the value requested (brought up-to-date if needed)
  301.     */
  302.    protected int get_value(
  303.      interactor from_obj, 
  304.      int        from_part, 
  305.      int        orient)
  306.      {
  307.        /* horizontal? */
  308.        if (orient == HORIZONTAL)
  309.      switch (from_part)
  310.        {
  311.        case PARTCODE_XY:
  312.          return from_obj.get_part(X);
  313.        case PARTCODE_XY2:
  314.          return from_obj.get_part(X) + from_obj.get_part(W);
  315.        case PARTCODE_WH:
  316.          return from_obj.get_part(W);
  317.        case PARTCODE_CENTER:
  318.          return from_obj.get_part(X) + (from_obj.get_part(W)/2);
  319.        case PARTCODE_VISIBLE:
  320.          return from_obj.get_part(VISIBLE);
  321.        case PARTCODE_ENABLED:
  322.          return from_obj.get_part(ENABLED);
  323.        case PARTCODE_PART_A:
  324.          return from_obj.get_part(PART_A);
  325.        case PARTCODE_PART_B:
  326.          return from_obj.get_part(PART_B);
  327.        default:
  328.          throw new sub_arctic_error("Bad part code ("+ from_part +
  329.                     ") in get_value()");
  330.        }
  331.        else
  332.      /* vertical */
  333.      switch (from_part)
  334.        {
  335.        case PARTCODE_XY:
  336.          return from_obj.get_part(Y);
  337.        case PARTCODE_XY2:
  338.          return from_obj.get_part(Y) + from_obj.get_part(H);
  339.        case PARTCODE_WH:
  340.          return from_obj.get_part(H);
  341.        case PARTCODE_CENTER:
  342.          return from_obj.get_part(Y) + (from_obj.get_part(H)/2);
  343.        case PARTCODE_VISIBLE:
  344.          return from_obj.get_part(VISIBLE);
  345.        case PARTCODE_ENABLED:
  346.          return from_obj.get_part(ENABLED);
  347.        case PARTCODE_PART_A:
  348.          return from_obj.get_part(PART_A);
  349.        case PARTCODE_PART_B:
  350.          return from_obj.get_part(PART_B);
  351.        default:
  352.          throw new sub_arctic_error("Bad part code ("+ from_part +
  353.                     ") in get_value()");
  354.        }
  355.      }
  356.  
  357.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  358.  
  359.    /** Fetch a particular value from a parent object on behalf of a given part 
  360.     *  in a particular orientation.  This is used for parent values only. It
  361.     *  applied coordinate transform for position values to place them in 
  362.     *  the local coordinates of the "from_obj" (which is the parent)<p>
  363.     *
  364.     * @see std_constraint_impl#get_parent_value
  365.     * @param interactor from_obj  object we are getting the value from
  366.     * @param int        from_part component of that object we want
  367.     * @param int        orient    orientation (should be HORIZONTAL or VERTICAL)
  368.     * @returns int the value requested (brought up-to-date if needed)
  369.     */
  370.    protected int get_parent_value(
  371.      interactor from_obj, 
  372.      int        from_part, 
  373.      int        orient)
  374.      {
  375.        /* horizontal? */
  376.        if (orient == HORIZONTAL)
  377.      switch (from_part)
  378.        {
  379.        case PARTCODE_XY:
  380.          return from_obj.x_into_local(from_obj.get_part(X));
  381.        case PARTCODE_XY2:
  382.          return from_obj.x_into_local(from_obj.get_part(X)) + 
  383.            from_obj.get_part(W);
  384.        case PARTCODE_WH:
  385.          return from_obj.get_part(W);
  386.        case PARTCODE_CENTER:
  387.          return from_obj.x_into_local(from_obj.get_part(X)) + 
  388.            (from_obj.get_part(W)/2);
  389.        case PARTCODE_VISIBLE:
  390.          return from_obj.get_part(VISIBLE);
  391.        case PARTCODE_ENABLED:
  392.          return from_obj.get_part(ENABLED);
  393.        case PARTCODE_PART_A:
  394.          return from_obj.get_part(PART_A);
  395.        case PARTCODE_PART_B:
  396.          return from_obj.get_part(PART_B);
  397.        default:
  398.          throw new sub_arctic_error("Bad part code in get_value()");
  399.        }
  400.        else
  401.      /* vertical */
  402.      switch (from_part)
  403.        {
  404.        case PARTCODE_XY:
  405.          return from_obj.y_into_local(from_obj.get_part(Y));
  406.        case PARTCODE_XY2:
  407.          return from_obj.y_into_local(from_obj.get_part(Y)) + 
  408.            from_obj.get_part(H);
  409.        case PARTCODE_WH:
  410.          return from_obj.get_part(H);
  411.        case PARTCODE_CENTER:
  412.          return from_obj.y_into_local(from_obj.get_part(Y)) + 
  413.            (from_obj.get_part(H)/2);
  414.        case PARTCODE_VISIBLE:
  415.          return from_obj.get_part(VISIBLE);
  416.        case PARTCODE_ENABLED:
  417.          return from_obj.get_part(ENABLED);
  418.        case PARTCODE_PART_A:
  419.          return from_obj.get_part(PART_A);
  420.        case PARTCODE_PART_B:
  421.          return from_obj.get_part(PART_B);
  422.        default:
  423.          throw new sub_arctic_error("Bad part code in get_value()");
  424.        }
  425.      }
  426.  
  427.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  428.  
  429.    /** 
  430.     * Fetch the indicated depended-upon value for the given object and part.<p>
  431.     *
  432.     * @param int        objpart_code encoding of object/part we need to fetch
  433.     * @param interactor constr_obj   constrained object we are fetching value 
  434.     *                                for. fetched values are found relative to 
  435.     *                                this object.
  436.     * @param int        orient       orientation of fetched value (should be
  437.     *                                HORIZONTAL or VERTICAL).
  438.     * @return int fetched value (brought up to date if necessary
  439.     */
  440.    public int fetch_value(
  441.      int        objpart_code, 
  442.      interactor constr_obj, 
  443.      int        orient) 
  444. {
  445.        int depend_on_obj;
  446.        int depend_on_part;
  447.        int cnt, i, v;
  448.        int value = 0;
  449.        interactor target = null;
  450.  
  451.        /* Sanity check */
  452.        if (constr_obj == null) 
  453.      throw new sub_arctic_error("Null constrained object passed to fetch_value()");
  454.  
  455.        /* extract the object and part from the encoding */
  456.        depend_on_obj  = std_objpart_encoding.object_encoded(objpart_code);
  457.        depend_on_part = std_objpart_encoding.part_encoded(objpart_code);
  458.  
  459.        /* get the value we depend on */
  460.        switch (depend_on_obj)
  461.          {
  462.        case OBJCODE_SELF: 
  463.          return get_value(constr_obj, depend_on_part, orient);
  464.  
  465.        /* . . . . . . . . . . */
  466.  
  467.            case OBJCODE_PARENT: 
  468.          /* get the parent -- if its null we return 0 */ 
  469.          target = constr_obj.parent();
  470.              if (target == null) return 0;
  471.  
  472.          /* if we are asking for X or Y they are always 0 for parent */
  473.          if (depend_on_part == PARTCODE_XY)
  474.            return 0;
  475.          else
  476.            /* get the value from the parent */
  477.            return  get_parent_value(target,depend_on_part,orient);
  478.  
  479.        /* . . . . . . . . . . */
  480.  
  481.        case OBJCODE_FIRST_CHILD: 
  482.          if (constr_obj.num_children() > 0)
  483.            {
  484.              /* get the first child */
  485.          target = constr_obj.child(0);
  486.              /* if it really exists, get the value */
  487.          if (target != null)
  488.            return get_value(target, depend_on_part, orient);
  489.            }
  490.          /* there are no children, or child is missing, return 0 */ 
  491.          return 0;
  492.  
  493.            case OBJCODE_LAST_CHILD: 
  494.          if (constr_obj.num_children() > 0)
  495.            {
  496.              /* get the first child */
  497.          target = constr_obj.child(constr_obj.num_children()-1);
  498.          /* if it really exists, get the value */
  499.          if (target != null)
  500.            return get_value(target, depend_on_part, orient);
  501.            }
  502.          /* there are no children, or child is missing, return 0 */ 
  503.          return 0;
  504.  
  505.            case OBJCODE_MAX_CHILD:
  506.          /* walk down children of constrained object and compute max */
  507.          value = Integer.MIN_VALUE;
  508.          cnt = 0;
  509.          for (i = 0; i < constr_obj.num_children(); i++)
  510.            {
  511.              /* extract the child and see if its real */
  512.          target = constr_obj.child(i);
  513.          if (target != null)
  514.            {
  515.              /* count it and get the value in question */
  516.              cnt++;
  517.              v = get_value(target, depend_on_part, orient);
  518.  
  519.              /* compute max */
  520.              if (v > value) value = v;
  521.            }
  522.            }
  523.  
  524.          /* treat zero children special */
  525.          if (cnt == 0) value = 0;  
  526.  
  527.          return value;
  528.  
  529.            case OBJCODE_MIN_CHILD:
  530.          /* walk down children of constrained object and compute min */
  531.          value = Integer.MAX_VALUE;
  532.          cnt = 0;
  533.          for (i = 0; i < constr_obj.num_children(); i++)
  534.            {
  535.              /* extract the child and see if its real */
  536.          target = constr_obj.child(i);
  537.          if (target != null)
  538.            {
  539.              /* count it and get the value in question */
  540.              cnt++;
  541.              v = get_value(target, depend_on_part, orient);
  542.  
  543.              /* compute min */
  544.              if (v < value) value = v;
  545.            }
  546.            }
  547.  
  548.          /* treat zero children special */
  549.          if (cnt == 0) value = 0;  
  550.  
  551.          return value;
  552.  
  553.        case OBJCODE_PREV_SIBLING:
  554.          /* get the sibling */
  555.          target = constr_obj.prev_sibling();
  556.  
  557.          /* if no sibling substitute zero */ 
  558.          if (target == null) return 0;
  559.  
  560.          /* otherwise get the value */
  561.              return get_value(target, depend_on_part, orient);
  562.  
  563.            case OBJCODE_NEXT_SIBLING:
  564.          /* get the sibling */
  565.          target = constr_obj.next_sibling();
  566.  
  567.          /* if its null supply edge of parent or zero */
  568.          if (target == null) 
  569.            {
  570.              switch(depend_on_part)
  571.                {
  572.              /* parent w/h substitutes for missing sibling edge */
  573.              case PARTCODE_XY:
  574.              case PARTCODE_XY2:
  575.                target = constr_obj.parent();
  576.  
  577.                /* if there is no parent return 0 */
  578.                 if (target == null) return  0;
  579.  
  580.                /* otherwise use its wh */
  581.                return get_value(target, PARTCODE_WH, orient);
  582.  
  583.              /* other cases go to zero */
  584.                  default: return 0;
  585.            }
  586.            }
  587.          else
  588.            /* return the normal value */
  589.            return get_value(target, depend_on_part, orient);
  590.  
  591.        default:
  592.          throw new sub_arctic_error("Bad object code " + depend_on_obj + 
  593.                      " passed to fetch_value()");
  594.          }
  595.      }
  596.  
  597.     //had:
  598.     //* @exception bad_value if a bad obj/part code or constrained object are 
  599.     //*                      passed.
  600.  
  601.    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  602.  
  603.   /** 
  604.    * Determine if a given constraint encoding represents "none" (i.e., that
  605.    * no constraint is to be applied).<p>
  606.    * 
  607.    * @param int enc  the encoding for the constraint.
  608.    * @return boolean whether the encoding indicates "none".
  609.    */
  610.    public boolean is_none(int enc)
  611.      {
  612.        return (enc & NONE_TEST_MASK) == NONE_TEST_VAL;
  613.      }
  614.  
  615.    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  616.  
  617.   /** 
  618.    * Determine if a given constraint encoding represents an external 
  619.    * constraint.<p>
  620.    * 
  621.    * @param int enc  the encoding for the constraint.
  622.    * @param boolean whether the encoding indicates an external constraint.
  623.    */
  624.    public boolean is_external(int enc)
  625.      {
  626.        return (enc & EXTERNAL_TEST_MASK) == EXTERNAL_TEST_VAL;
  627.      }
  628.  
  629.    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  630.  
  631.   /** 
  632.    * Evaluate an encoded constraint (under a given orientation).  The 
  633.    * constraint is being applied to the given part of the given object (i.e. 
  634.    * the constr_part part of the constr_obj object).  The encoding typically 
  635.    * will designate parameter values relative to that object (i.e. the width 
  636.    * of the parent of the object). <p>
  637.    *
  638.    * @param int        enc         the encoding of the constraint
  639.    * @param interactor constr_obj  the object being constrained
  640.    * @param int        constr_part the part being constrained
  641.    * @param int        orient      the orientation of the constraint
  642.    * @return int the result of the evaluation
  643.    */
  644.    public int eval(
  645.      int        enc, 
  646.      interactor constr_obj, 
  647.      int        constr_part,
  648.      int        orient) 
  649. {
  650.        /* bail out early with same value if the constraint is "none".  */
  651.        if (is_none(enc)) return constr_obj.get_part(constr_part);
  652.  
  653.        /* send work to one of the classes for different numbers of operands */
  654.        switch(num_ops(enc))
  655.      {
  656.        case 0: return op0_impl.eval(enc, constr_obj, constr_part,orient);
  657.        case 1: return op1_impl.eval(enc, constr_obj, constr_part,orient);
  658.        case 2: return op2_impl.eval(enc, constr_obj, constr_part,orient);
  659.        case 3: return op3_impl.eval(enc, constr_obj, constr_part,orient);
  660.        default: throw new sub_arctic_error("Unrecognized constraint encoding " + 
  661.                             "passed to std_constraint_impl.eval()");
  662.      }
  663.      }
  664.  
  665.    //had:
  666.    //* @exception bad_value if the encoding, or constrained object/part are 
  667.    //*                      malformed
  668.  
  669.    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  670.  
  671.   /** Test whether the given encoded constraint depends on the indicated 
  672.    *  neighboring object and part.  The constraint is attached to the 
  673.    *  constr_obj object and this test is expressed relative to that object.  
  674.    *  The object and part that we determining dependency upon is encoded in
  675.    *  test_which_obj and test_which_part.  For tests of child objects, an
  676.    *  indication of the index of that child is also given.<p>
  677.    *
  678.    *  If this is an "external" constraint that maintains its own dependency
  679.    *  edges and works through the external notification system, then this 
  680.    *  method may safely return false in all cases.<p>
  681.    *
  682.    * @param int        enc             The encoding for the constraint.
  683.    * @param interactor constr_obj      The object the constraint is attached to
  684.    * @param int        test_which_obj  The neighboring object we are asking 
  685.    *                                   about.  This can be one of the values 
  686.    *                                   OBJCODE_SELF, OBJCODE_PARENT, 
  687.    *                                   OBJCODE_SOME_CHILD, 
  688.    *                                   OBJCODE_PREV_SIBLING, or 
  689.    *                                   OBJCODE_NEXT_SIBLING.  
  690.    * @param int        test_which_part The part we are asking about.
  691.    * @param int        nth_child       for SOME_CHILD, this provides the index
  692.    *                       of the child (and is ignored otherwise).
  693.    * @param int        orient          Orientation of the constraint.  This 
  694.    *                                   should be HORIZONTAL or VERTICAL.
  695.    * @return boolean whether the given constraint depends upon the given value
  696.    */
  697.    public boolean depends_on(
  698.      int        enc, 
  699.      interactor constr_obj,
  700.      int        which_obj, 
  701.      int        which_part, 
  702.      int        nth_child,
  703.      int        orient) 
  704. {
  705.        /* bail out early with same value if the constraint is "none".  */
  706.        if (is_none(enc)) return false;
  707.  
  708.        /* send work to one of the classes for different numbers of operands */
  709.        switch(num_ops(enc))
  710.      {
  711.        case 0: 
  712.          return op0_impl.depends_on(enc, constr_obj, which_obj, 
  713.                            which_part, nth_child, orient);
  714.        case 1: return op1_impl.depends_on(enc, constr_obj, which_obj, 
  715.                            which_part, nth_child, orient);
  716.        case 2: return op2_impl.depends_on(enc, constr_obj, which_obj, 
  717.                            which_part, nth_child, orient);
  718.        case 3: return op3_impl.depends_on(enc, constr_obj, which_obj, 
  719.                            which_part, nth_child, orient);
  720.        default: throw new sub_arctic_error("Unrecognized constraint encoding " +
  721.                 "passed to std_constraint_impl.depends_on()");
  722.      }
  723.      }
  724.  
  725.    //had:
  726.    //* @exception bad_value if one of the parameters has an unrecognized value
  727.  
  728.    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  729.  
  730.    /** Test whether the given encoded object/part indicates the given 
  731.     *  object and part for dependency purposes.  For example, 
  732.     *  part_depends_on(enc, cobj, OBJCODE_PARENT, PARTCODE_W, 0, HORIZONTAL)
  733.     *  would test if the object/part encoded in enc and part of the constraint
  734.     *  attached to cobj indicates a dependency on the width of the parent of 
  735.     *  cobj.
  736.     *
  737.     * @param int        enc             The encoding we are testing.
  738.     * @param interactor constr_obj      The object the constraint is attached to
  739.     * @param int        test_which_obj  The object we are asking about.  This 
  740.     *                                   can be one of the values OBJCODE_SELF, 
  741.     *                                   OBJCODE_PARENT, OBJCODE_SOME_CHILD, 
  742.     *                                   OBJCODE_PREV_SIBLING, or 
  743.     *                                   OBJCODE_NEXT_SIBLING.  
  744.     * @param int        test_which_part The part we are asking about.
  745.     * @param int        nth_child       for SOME_CHILD, this provides the index
  746.     *                    of the child (and is ignored otherwise).
  747.     * @param int        orient          Orientation of the constraint.  This 
  748.     *                                   should be HORIZONTAL or VERTICAL.
  749.     * @return boolean whether the given constraint depends upon the given value
  750.     */
  751.    public boolean part_depends_on(
  752.      int        enc, 
  753.      interactor constr_obj,
  754.      int        which_obj, 
  755.      int        which_part, 
  756.      int        nth_child,
  757.      int        orient) 
  758. {
  759.        int d_obj, d_part, n_child;
  760.  
  761.        /* pull out the encoded object */
  762.        d_obj =  (enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
  763.  
  764.        /* if they are not talking about the same object we fail */
  765.        switch(which_obj)
  766.      {
  767.        case OBJCODE_SELF:
  768.          if (d_obj != OBJCODE_SELF) return false;
  769.        break;
  770.  
  771.        case OBJCODE_PARENT:
  772.          if (d_obj != OBJCODE_PARENT)
  773.            {
  774.          /* next sibling falls back on parent if there is none */
  775.          if (d_obj == OBJCODE_NEXT_SIBLING && 
  776.              constr_obj.next_sibling() == null)
  777.            {
  778.              /* but only on xy and xy2 */
  779.              d_part = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
  780.              return d_part == PARTCODE_XY || d_part == PARTCODE_XY2;
  781.            }
  782.          /* not the special case and doesn't match parent */
  783.          return false;
  784.            }
  785.        break;
  786.  
  787.        case OBJCODE_PREV_SIBLING:
  788.          if (d_obj != OBJCODE_PREV_SIBLING) return false;
  789.        break;
  790.  
  791.        case OBJCODE_NEXT_SIBLING:
  792.          if (d_obj != OBJCODE_NEXT_SIBLING) return false;
  793.        break;
  794.  
  795.        case OBJCODE_SOME_CHILD:
  796.          /* max/min child depend on any/all children */
  797.          if (d_obj != OBJCODE_MAX_CHILD &&  d_obj != OBJCODE_MIN_CHILD)
  798.            {
  799.          /* see if we match as first or last child */
  800.          n_child = constr_obj.num_children();
  801.          if (!(d_obj==OBJCODE_FIRST_CHILD && n_child>0&&nth_child==0)&&
  802.              !(d_obj==OBJCODE_LAST_CHILD && nth_child == n_child-1))
  803.            return false;
  804.            }
  805.        break;
  806.  
  807.        default:
  808.          throw new sub_arctic_error("Unknown object kind passed to " + 
  809.                  "std_constraint_impl.part_depends_on()");
  810.      }
  811.  
  812.        /* if we make it here, then we have determined that we are talking 
  813.     * about the same object.  Now we look at the part code. */
  814.        d_part = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
  815.        if (orient == HORIZONTAL)
  816.          switch(which_part)
  817.        {
  818.          case X:  return d_part == PARTCODE_XY || 
  819.                      d_part == PARTCODE_XY2 ||
  820.                          d_part == PARTCODE_CENTER;
  821.          case W:  return d_part == PARTCODE_WH ||
  822.                      d_part == PARTCODE_XY2 ||
  823.                          d_part == PARTCODE_CENTER;
  824.          case VISIBLE: return d_part == PARTCODE_VISIBLE;
  825.          case ENABLED: return d_part == PARTCODE_ENABLED;
  826.          case PART_A:   return d_part == PARTCODE_PART_A;
  827.          case PART_B:   return d_part == PARTCODE_PART_B;
  828.          default: return false;
  829.        }
  830.       else
  831.          switch(which_part)
  832.        {
  833.          case Y:  return d_part == PARTCODE_XY || 
  834.                      d_part == PARTCODE_XY2 ||
  835.                          d_part == PARTCODE_CENTER;
  836.          case H:  return d_part == PARTCODE_WH ||
  837.                      d_part == PARTCODE_XY2 ||
  838.                          d_part == PARTCODE_CENTER;
  839.          case VISIBLE: return d_part == PARTCODE_VISIBLE;
  840.          case ENABLED: return d_part == PARTCODE_ENABLED;
  841.          case PART_A:   return d_part == PARTCODE_PART_A;
  842.          case PART_B:   return d_part == PARTCODE_PART_B;
  843.          default: return false;
  844.        }
  845.      } 
  846.  
  847.     //had:
  848.     //* @exception bad_value if one of the parameters has an unrecognized value
  849.  
  850.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  851.  
  852.   /**
  853.    * Extract the set of objects/parts that a constraint depends on.  This
  854.    * produces a Vector with pairs of entries, the first being an interactor,
  855.    * and the second being an Integer which is the part number of that 
  856.    * interactor that is depended upon.<p>
  857.    *
  858.    * @param int        enc        encoding value for the constraint in question.
  859.    * @param interactor constr_obj the object the constraint is attached to 
  860.    *                              (hence its referents are relative to).
  861.    * @param int        orient     Orientation of the constraint.  This 
  862.    *                              should be HORIZONTAL or VERTICAL.
  863.    * @return Vector containing pairs of objects, the first being an interactor
  864.    *                which is depended upon, and the second being an Integer
  865.    *                giving the part number of the part depended upon.
  866.    */
  867.   public Vector depend_list(int enc, interactor constr_obj, int orient) 
  868. {
  869.       /* send work to one of the classes for different numbers of operands */
  870.       switch(num_ops(enc))
  871.         {
  872.           case 0: 
  873.             return op0_impl.mk_depend_list(enc, constr_obj, orient);
  874.           case 1: 
  875.         return op1_impl.mk_depend_list(enc, constr_obj, orient);
  876.           case 2: 
  877.         return op2_impl.mk_depend_list(enc, constr_obj, orient);
  878.           case 3: 
  879.         return op3_impl.mk_depend_list(enc, constr_obj, orient);
  880.           default: 
  881.         throw new sub_arctic_error("Unrecognized constraint encoding " +
  882.                 "passed to std_constraint_impl.depend_list()");
  883.         }
  884.     }
  885.  
  886.    //had:
  887.    //* @exception bad_value if one of the parameters is malformed.
  888.  
  889.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  890.  
  891.   /** 
  892.    * Extract the dependencies that are implicit in the particular operation
  893.    * encoded in the given standard constraint encoding. <p>
  894.    * 
  895.    * @param int        enc        encoding value for the constraint in question.
  896.    * @param interactor constr_obj the object the constraint is attached to 
  897.    *                              (hence its referents are relative to).
  898.    * @param int        orient     Orientation of the constraint.  This
  899.    *                              should be HORIZONTAL or VERTICAL.
  900.    * @return Vector containing pairs of objects, the first being an interactor
  901.    *                which is depended upon, and the second being an Integer
  902.    *                giving the part number of the part depended upon.
  903.    */
  904.   public Vector implicit_depend_list(int enc, interactor constr_obj, int orient) 
  905. {
  906.       /* send work to one of the classes for different numbers of operands */
  907.       switch(num_ops(enc))
  908.         {
  909.           case 0: 
  910.             return op0_impl.mk_implicit_depend_list(enc, constr_obj, orient);
  911.           case 1: 
  912.         return op1_impl.mk_implicit_depend_list(enc, constr_obj, orient);
  913.           case 2: 
  914.         return op2_impl.mk_implicit_depend_list(enc, constr_obj, orient);
  915.           case 3: 
  916.         return op3_impl.mk_implicit_depend_list(enc, constr_obj, orient);
  917.           default: 
  918.         throw new sub_arctic_error("Unrecognized constraint encoding " +
  919.             "passed to std_constraint_impl.implicit_depend_list()");
  920.         }
  921.     }
  922.  
  923.    //had:
  924.    //* @exception bad_value if the encoding value is not valid.
  925.  
  926.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  927.  
  928.   /** 
  929.    * Extract a depended upon object/part from the given object/part encoding
  930.    * and add it to the end of the given vector.  This is used by depend_list()
  931.    * to produce parts of its result.  Appended to the Vector will be two values,
  932.    * an interactor which is the object depended upon, and an Integer with the 
  933.    * part number within that object that is depended upon.<p>
  934.    *
  935.    * @param Vector     result     the Vector object we add to the end of.
  936.    * @param int        part_enc   encoding value for object/part in question.
  937.    * @param interactor constr_obj the object the constraint is attached to 
  938.    *                              (hence its referents are relative to).
  939.    * @param int        orient     Orientation of the constraint.  This 
  940.    *                              should be HORIZONTAL or VERTICAL.
  941.    */
  942.   protected void add_depend_obj_part(
  943.     Vector result, 
  944.     int part_enc, 
  945.     interactor constr_obj, 
  946.     int orient) 
  947. {
  948.        int d_obj, d_part, i;
  949.  
  950.        /* pull out the encoded object and part */
  951.        d_obj =  (part_enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
  952.        d_part = (part_enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
  953.  
  954.        /* append interactor corresponding to encoded object */
  955.        switch(d_obj)
  956.      {
  957.        case OBJCODE_SELF:
  958.          result.addElement(constr_obj);
  959.        break;
  960.  
  961.        case OBJCODE_PARENT:
  962.          if (constr_obj.parent() == null) return;
  963.          result.addElement(constr_obj.parent());
  964.        break;
  965.  
  966.        case OBJCODE_PREV_SIBLING:
  967.          if (constr_obj.prev_sibling() == null) return;
  968.              result.addElement(constr_obj.prev_sibling());
  969.        break;
  970.  
  971.        case OBJCODE_NEXT_SIBLING:
  972.          if (constr_obj.next_sibling() != null)
  973.            result.addElement(constr_obj.next_sibling());
  974.          else
  975.            {
  976.          /* special case for next_sibling fallback to parent */
  977.          if (constr_obj.parent() == null) return;
  978.  
  979.          /* but only for XY or XY2 */
  980.          if (d_part != PARTCODE_XY && d_part != PARTCODE_XY2) return;
  981.  
  982.          /* fallback to parent.xy2 */
  983.          result.addElement(constr_obj.parent());
  984.          d_part = PARTCODE_XY2;
  985.            }
  986.        break;
  987.  
  988.        case OBJCODE_FIRST_CHILD:
  989.          if (constr_obj.num_children() >= 1)
  990.            result.addElement(constr_obj.child(0));
  991.          else
  992.            return;
  993.        break;
  994.  
  995.        case OBJCODE_LAST_CHILD:
  996.          if (constr_obj.num_children() >= 1)
  997.            result.addElement(
  998.                  constr_obj.child(constr_obj.
  999.                           num_children()-1));
  1000.          else
  1001.            return;
  1002.          break;
  1003.  
  1004.        case OBJCODE_MAX_CHILD:
  1005.        case OBJCODE_MIN_CHILD:
  1006.          /* we are dependent on every child */
  1007.          for (i = 0; i < constr_obj.num_children(); i++)
  1008.            {
  1009.          /* add the child and the part */
  1010.          result.addElement(constr_obj.child(i));
  1011.          add_depend_part(result, d_part, orient);
  1012.            }
  1013.          return;
  1014.  
  1015.        default:
  1016.          throw new sub_arctic_error("Unknown object kind passed to " + 
  1017.                  "std_constraint_impl.part_depends_on()");
  1018.      }
  1019.  
  1020.        /* now do the part */
  1021.        add_depend_part(result, d_part, orient);
  1022.     }
  1023.  
  1024.    //had:
  1025.    //* @exception bad_value if one of the parameters is malformed.
  1026.  
  1027.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  1028.  
  1029.   /** 
  1030.    * Append depended upon part numbers to the given Vector.  This assumes
  1031.    * that the last element of the vector contains the object depended on.
  1032.    * If the part encoding given requires multiple dependencies additional
  1033.    * dependent object values will be added so that we always have object/part
  1034.    * pairs.<p>
  1035.    *
  1036.    * @param Vector     result     the Vector object we add to the end of.
  1037.    * @param int        part_enc   encoding value for part in question.
  1038.    * @param int        orient     Orientation of the constraint.  This 
  1039.    *                              should be HORIZONTAL or VERTICAL.
  1040.    */
  1041.   protected void add_depend_part(
  1042.     Vector result, 
  1043.     int part_enc, 
  1044.     int orient)
  1045.     {
  1046.       interactor dep_obj = (interactor)result.elementAt(result.size()-1);
  1047.  
  1048.       switch (part_enc)
  1049.     {
  1050.       case PARTCODE_XY:
  1051.         if (orient == HORIZONTAL)
  1052.           result.addElement(new Integer(X));
  1053.         else
  1054.           result.addElement(new Integer(Y));
  1055.       break;
  1056.  
  1057.       case PARTCODE_CENTER:
  1058.       case PARTCODE_XY2:
  1059.         if (orient == HORIZONTAL)
  1060.           {
  1061.             result.addElement(new Integer(X));
  1062.         result.addElement(dep_obj);
  1063.             result.addElement(new Integer(W));
  1064.           }
  1065.         else
  1066.           {
  1067.             result.addElement(new Integer(Y));
  1068.         result.addElement(dep_obj);
  1069.             result.addElement(new Integer(H));
  1070.           }
  1071.       break;
  1072.  
  1073.       case PARTCODE_WH:
  1074.         if (orient == HORIZONTAL)
  1075.           result.addElement(new Integer(W));
  1076.         else
  1077.           result.addElement(new Integer(H));
  1078.       break;
  1079.  
  1080.       case PARTCODE_VISIBLE:
  1081.         result.addElement(new Integer(VISIBLE));
  1082.       break;
  1083.  
  1084.       case PARTCODE_ENABLED:
  1085.         result.addElement(new Integer(ENABLED));
  1086.       break;
  1087.  
  1088.       case PARTCODE_PART_A:
  1089.         result.addElement(new Integer(PART_A));
  1090.       break;
  1091.       case PARTCODE_PART_B:
  1092.         result.addElement(new Integer(PART_B));
  1093.       break;
  1094.     }
  1095.     }
  1096.  
  1097.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  1098. }
  1099.  
  1100. /*=========================== COPYRIGHT NOTICE ===========================
  1101.  
  1102. This file is part of the subArctic user interface toolkit.
  1103.  
  1104. Copyright (c) 1996 Scott Hudson and Ian Smith
  1105. All rights reserved.
  1106.  
  1107. The subArctic system is freely available for most uses under the terms
  1108. and conditions described in 
  1109.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  1110. and appearing in full in the lib/interactor.java source file.
  1111.  
  1112. The current release and additional information about this software can be 
  1113. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  1114.  
  1115. ========================================================================*/
  1116.